package com.xiaoyi.springboot.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaoyi.springboot.config.ResponseHelper;
import com.xiaoyi.springboot.config.ResponseModel;
import com.xiaoyi.springboot.constant.Constants;
import com.xiaoyi.springboot.entity.SysUser;
import com.xiaoyi.springboot.enums.UserType;
import com.xiaoyi.springboot.service.RedisService;
import com.xiaoyi.springboot.service.SysUserService;
import com.xiaoyi.springboot.shiro.JwtToken;
import com.xiaoyi.springboot.shiro.JwtUtil;
import com.xiaoyi.springboot.util.CommonConstant;
import com.xiaoyi.springboot.util.PasswordUtil;
import com.xiaoyi.springboot.util.StringUtils;
import com.xiaoyi.springboot.vo.SysUserRepVo;
import com.xiaoyi.springboot.vo.UserLoginReqVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.Objects;

/**
 *
 * @author xiaoyi
 * @date 2021/10/9 23:06
 * @version v1.0
 */
@RestController
@RequestMapping("/sys")
@Api(tags="用户登录")
@Slf4j
public class LoginController {
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private RedisService redisService;
	@ApiOperation("登录接口")
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public ResponseModel<JSONObject> login(@RequestBody UserLoginReqVo userLoginVo){
		ResponseModel<JSONObject> result = new ResponseModel<JSONObject>();
		String username = userLoginVo.getUsername();
		String password = userLoginVo.getPassword();

		//1. 校验用户是否有效
		//update-begin-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug，if条件永远为false
		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(SysUser::getUsername,username);
		SysUser sysUser = sysUserService.getOne(queryWrapper);
		if (Objects.isNull(sysUser)){
			return ResponseHelper.validationFailure("用户名或密码错误");
		}
		
		//2. 校验用户名或密码是否正确
		String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
		String syspassword = sysUser.getPassword();
		if (!syspassword.equals(userpassword)) {
			return ResponseHelper.validationFailure("用户名或密码错误");
		}
		//用户登录信息
		;
		try {
			return ResponseHelper.buildResponseModel(userInfo(sysUser));
		} catch (UnsupportedEncodingException e) {
			return ResponseHelper.validationFailure("用户名或密码错误");
		}
	}
	
	/**
	 * 退出登录
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/logout")
	public ResponseModel<Object> logout(HttpServletRequest request, HttpServletResponse response) {
		//用户退出逻辑
	    String token = request.getHeader(Constants.X_ACCESS_TOKEN);
	    if(StringUtils.isEmpty(token)) {
	    	return ResponseHelper.validationFailure("退出登录失败！");
	    }
	    String username = JwtUtil.getUsername(token);
		SysUser sysUser = sysUserService.getUserByName(username);
	    if(sysUser!=null) {
	    	log.info(" 用户名:  "+sysUser.getRealname()+",退出成功！ ");
	    	//清空用户登录Token缓存
			redisService.del(CommonConstant.PREFIX_USER_TOKEN + token);
	    	//清空用户登录Shiro权限缓存
			redisService.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
			//清空用户的缓存信息（包括部门信息），例如sys:cache:user::<username>
			redisService.del(String.format("%s::%s", Constants.SYS_USERS_CACHE, sysUser.getUsername()));
			//调用shiro的logout
			SecurityUtils.getSubject().logout();
	    	return ResponseHelper.buildResponseModel("退出登录成功！");
	    }else {
	    	return ResponseHelper.buildResponseModel("Token无效!");
	    }
	}
	/**
	 * 用户信息
	 *
	 * @param sysUser
	 * @return
	 */
	private JSONObject userInfo(SysUser sysUser) throws UnsupportedEncodingException {
		String syspassword = sysUser.getPassword();
		String username = sysUser.getUsername();
		// 生成token

//		SecurityUtils.getSubject().getSession().setAttribute("admin",(SysUser)subject.getPrincipal());
		String token = JwtUtil.sign(username, syspassword,UserType.ADMINUSER.getValue());
		// 设置token缓存有效时间
		redisService.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
		redisService.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
		JSONObject obj = new JSONObject();
		obj.put("token", token);
		SysUserRepVo sysUserRepVo = new SysUserRepVo();
		BeanUtils.copyProperties(sysUser,sysUserRepVo);
		obj.put("userInfo", sysUserRepVo);
		return obj;
	}
}